home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / shllutil.lha / shellutils-1.8 / src / id.c < prev    next >
C/C++ Source or Header  |  1992-10-28  |  7KB  |  347 lines

  1. /* id -- print real and effective UIDs and GIDs
  2.    Copyright (C) 1989, 1991 Free Software Foundation.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /* Written by Arnold Robbins, arnold@audiofax.com.
  19.    Major rewrite by David MacKenzie, djm@gnu.ai.mit.edu. */
  20.  
  21. #include <stdio.h>
  22. #include <getopt.h>
  23. #include <sys/types.h>
  24. #include <pwd.h>
  25. #include <grp.h>
  26. #include "system.h"
  27.  
  28. #ifdef _POSIX_VERSION
  29. #include <limits.h>
  30. #if !defined(NGROUPS_MAX) || NGROUPS_MAX < 1
  31. #define NGROUPS_MAX sysconf (_SC_NGROUPS_MAX)
  32. #endif /* !NGROUPS_MAX */
  33.  
  34. /* Even though SunOS 4, Ultrix 4, and 386BSD are mostly POSIX.1 compliant,
  35.    their getgroups system call (except in the `System V' environment, which
  36.    is troublesome in other ways) fills in an array of int, not gid_t
  37.    (which is `short' on those systems).  Kludge, kludge.  */
  38.  
  39. #if !defined(sun) && !defined(ultrix) && !defined(__386BSD__)
  40. #define GETGROUPS_T gid_t
  41. #else /* sun or ultrix or 386BSD */
  42. #define GETGROUPS_T int
  43. #endif /* sun or ultrix or 386BSD */
  44. #else /* not _POSIX_VERSION */
  45. struct passwd *getpwuid ();
  46. struct group *getgrgid ();
  47. uid_t getuid ();
  48. gid_t getgid ();
  49. uid_t geteuid ();
  50. gid_t getegid ();
  51. #include <sys/param.h>
  52. #if !defined(NGROUPS_MAX) && defined(NGROUPS)
  53. #define NGROUPS_MAX NGROUPS
  54. #endif /* not NGROUPS_MAX and NGROUPS */
  55. #define GETGROUPS_T int
  56. #endif /* not _POSIX_VERSION */
  57.  
  58. char *xmalloc ();
  59. int getugroups ();
  60. void error ();
  61. void print_user ();
  62. void print_group ();
  63. void print_group_list ();
  64. void print_full_info ();
  65. void usage ();
  66.  
  67. /* The name this program was run with. */
  68. char *program_name;
  69.  
  70. /* If nonzero, output only the group ID(s). -g */
  71. int just_group = 0;
  72.  
  73. /* If nonzero, output user/group name instead of ID number. -n */
  74. int use_name = 0;
  75.  
  76. /* If nonzero, output real UID/GID instead of default effective UID/GID. -r */
  77. int use_real = 0;
  78.  
  79. /* If nonzero, output only the user ID(s). -u */
  80. int just_user = 0;
  81.  
  82. /* If nonzero, output only the supplementary groups. -G */
  83. int just_group_list = 0;
  84.  
  85. /* The real and effective IDs of the user to print. */
  86. uid_t ruid, euid;
  87. gid_t rgid, egid;
  88.  
  89. /* The number of errors encountered so far. */
  90. int problems = 0;
  91.  
  92. struct option longopts[] =
  93. {
  94.   {"group", 0, NULL, 'g'},
  95.   {"name", 0, NULL, 'n'},
  96.   {"real", 0, NULL, 'r'},
  97.   {"user", 0, NULL, 'u'},
  98.   {"groups", 0, NULL, 'G'},
  99.   {NULL, 0, NULL, 0}
  100. };
  101.  
  102. void
  103. main (argc, argv)
  104.      int argc;
  105.      char **argv;
  106. {
  107.   int optc;
  108.  
  109.   program_name = argv[0];
  110.  
  111.   while ((optc = getopt_long (argc, argv, "gnruG", longopts, (int *) 0))
  112.      != EOF)
  113.     {
  114.       switch (optc)
  115.     {
  116.     case 'g':
  117.       just_group = 1;
  118.       break;
  119.     case 'n':
  120.       use_name = 1;
  121.       break;
  122.     case 'r':
  123.       use_real = 1;
  124.       break;
  125.     case 'u':
  126.       just_user = 1;
  127.       break;
  128.     case 'G':
  129.       just_group_list = 1;
  130.       break;
  131.     default:
  132.       usage ();
  133.     }
  134.     }
  135.  
  136.   if (just_user + just_group + just_group_list > 1)
  137.     error (1, 0, "cannot print only user and only group");
  138.  
  139.   if (just_user + just_group + just_group_list == 0 && (use_real || use_name))
  140.     error (1, 0, "cannot print only names or real IDs in default format");
  141.  
  142.   if (argc - optind > 1)
  143.     usage ();
  144.  
  145.   if (argc - optind == 1)
  146.     {
  147.       struct passwd *pwd = getpwnam (argv[optind]);
  148.       if (pwd == NULL)
  149.     error (1, 0, "%s: No such user", argv[optind]);
  150.       ruid = euid = pwd->pw_uid;
  151.       rgid = egid = pwd->pw_gid;
  152.     }
  153.   else
  154.     {
  155.       euid = geteuid ();
  156.       ruid = getuid ();
  157.       egid = getegid ();
  158.       rgid = getgid ();
  159.     }
  160.  
  161.   if (just_user)
  162.     print_user (use_real ? ruid : euid);
  163.   else if (just_group)
  164.     print_group (use_real ? rgid : egid);
  165.   else if (just_group_list)
  166.     print_group_list (argv[optind]);
  167.   else
  168.     print_full_info (argv[optind]);
  169.   putchar ('\n');
  170.  
  171.   exit (problems != 0);
  172. }
  173.  
  174. /* Print the name or value of user ID UID. */
  175.  
  176. void
  177. print_user (uid)
  178.      int uid;
  179. {
  180.   struct passwd *pwd = NULL;
  181.  
  182.   if (use_name)
  183.     {
  184.       pwd = getpwuid (uid);
  185.       if (pwd == NULL)
  186.     problems++;
  187.     }
  188.  
  189.   if (pwd == NULL)
  190.     printf ("%u", (unsigned) uid);
  191.   else
  192.     printf ("%s", pwd->pw_name);
  193. }
  194.  
  195. /* Print the name or value of group ID GID. */
  196.  
  197. void
  198. print_group (gid)
  199.      int gid;
  200. {
  201.   struct group *grp = NULL;
  202.  
  203.   if (use_name)
  204.     {
  205.       grp = getgrgid (gid);
  206.       if (grp == NULL)
  207.     problems++;
  208.     }
  209.  
  210.   if (grp == NULL)
  211.     printf ("%u", (unsigned) gid);
  212.   else
  213.     printf ("%s", grp->gr_name);
  214. }
  215.  
  216. /* Print all of the distinct groups the user is in . */
  217.  
  218. void
  219. print_group_list (username)
  220.      char *username;
  221. {
  222.   print_group (rgid);
  223.   if (egid != rgid)
  224.     {
  225.       putchar (' ');
  226.       print_group (egid);
  227.     }
  228.  
  229. #ifdef NGROUPS_MAX
  230.   {
  231.     int ngroups;
  232.     GETGROUPS_T *groups;
  233.     register int i;
  234.  
  235.     groups = (GETGROUPS_T *) xmalloc (NGROUPS_MAX * sizeof (GETGROUPS_T));
  236.     if (username == 0)
  237.       ngroups = getgroups (NGROUPS_MAX, groups);
  238.     else
  239.       ngroups = getugroups (NGROUPS_MAX, groups, username);
  240.     if (ngroups < 0)
  241.       {
  242.     error (0, errno, "cannot get supplemental group list");
  243.     problems++;
  244.     free (groups);
  245.     return;
  246.       }
  247.  
  248.     for (i = 0; i < ngroups; i++)
  249.       if (groups[i] != rgid && groups[i] != egid)
  250.     {
  251.       putchar (' ');
  252.       print_group (groups[i]);
  253.     }
  254.     free (groups);
  255.   }
  256. #endif
  257. }
  258.  
  259. /* Print all of the info about the user's user and group IDs. */
  260.  
  261. void
  262. print_full_info (username)
  263.      char *username;
  264. {
  265.   struct passwd *pwd;
  266.   struct group *grp;
  267.  
  268.   printf ("uid=%u", (unsigned) ruid);
  269.   pwd = getpwuid (ruid);
  270.   if (pwd == NULL)
  271.     problems++;
  272.   else
  273.     printf ("(%s)", pwd->pw_name);
  274.   
  275.   printf (" gid=%u", (unsigned) rgid);
  276.   grp = getgrgid (rgid);
  277.   if (grp == NULL)
  278.     problems++;
  279.   else
  280.     printf ("(%s)", grp->gr_name);
  281.   
  282.   if (euid != ruid)
  283.     {
  284.       printf (" euid=%u", (unsigned) euid);
  285.       pwd = getpwuid (euid);
  286.       if (pwd == NULL)
  287.     problems++;
  288.       else
  289.     printf ("(%s)", pwd->pw_name);
  290.     }
  291.   
  292.   if (egid != rgid)
  293.     {
  294.       printf (" egid=%u", (unsigned) egid);
  295.       grp = getgrgid (egid);
  296.       if (grp == NULL)
  297.     problems++;
  298.       else
  299.     printf ("(%s)", grp->gr_name);
  300.     }
  301.  
  302. #ifdef NGROUPS_MAX
  303.   {
  304.     int ngroups;
  305.     GETGROUPS_T *groups;
  306.     register int i;
  307.  
  308.     groups = (GETGROUPS_T *) xmalloc (NGROUPS_MAX * sizeof (GETGROUPS_T));
  309.     if (username == 0)
  310.       ngroups = getgroups (NGROUPS_MAX, groups);
  311.     else
  312.       ngroups = getugroups (NGROUPS_MAX, groups, username);
  313.     if (ngroups < 0)
  314.       {
  315.     error (0, errno, "cannot get supplemental group list");
  316.     problems++;
  317.     free (groups);
  318.     return;
  319.       }
  320.  
  321.     if (ngroups > 0)
  322.       fputs (" groups=", stdout);
  323.     for (i = 0; i < ngroups; i++)
  324.       {
  325.     if (i > 0)
  326.       putchar (',');
  327.     printf ("%u", (unsigned) groups[i]);
  328.     grp = getgrgid (groups[i]);
  329.     if (grp == NULL)
  330.       problems++;
  331.     else
  332.       printf ("(%s)", grp->gr_name);
  333.       }
  334.     free (groups);
  335.   }
  336. #endif
  337. }
  338.  
  339. void
  340. usage ()
  341. {
  342.   fprintf (stderr, "\
  343. Usage: %s [-gnruG] [--group] [--name] [--real] [--user] [--groups] [username]\n",
  344.        program_name);
  345.   exit (1);
  346. }
  347.